package com.lagou.edu.message.server;

import com.corundumstudio.socketio.*;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.corundumstudio.socketio.listener.ExceptionListener;
import com.corundumstudio.socketio.namespace.Namespace;
import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.protocol.PacketType;
import com.lagou.edu.common.jwt.JwtUtil;
import com.lagou.edu.message.api.dto.Message;
import com.lagou.edu.message.server.store.StoreFacotryProvider;
import com.lagou.edu.message.util.PushUtils;
import com.lagou.edu.message.util.ServerConfigUtils;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class PushServer {

    public static final PushServer pushServer = new PushServer();

    private static List<SocketIOClient> clients = new ArrayList<SocketIOClient>();//用于保存所有客户端
//    private Namespace pushNamespace;
    private SocketIOServer server;

    private PushServer() {
        Configuration config = new Configuration();
        config.setStoreFactory(StoreFacotryProvider.getRedissonStoreFactory());
        config.setAuthorizationListener(new UserAuthorizationListener());
        config.setContext(ServerConfigUtils.instance.getWebSocketContext());
        config.setHostname(ServerConfigUtils.instance.getWebSocketOrigin());
        config.setPort(ServerConfigUtils.instance.getWebSocketPort());

        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setReuseAddress(true);
        config.setSocketConfig(socketConfig);

        this.server = new SocketIOServer(config);

//        server.addNamespace(ServerConfigUtils.instance.getWebSocketContext());


        //添加创建连接的监听器
        this.server.addConnectListener(new ConnectListener() {

            @Override
            public void onConnect(SocketIOClient client) {


                JwtUtil.JwtResult userInfo = UserAuthorizationListener.getUserInfo(client.getHandshakeData());

                if (userInfo != null){
                    Set<String> allRooms = client.getAllRooms();
                    for (String room:allRooms){
                        client.leaveRoom(room);
                    }
                    Integer userId = userInfo.getUserId();
                    List<String> roomList = PushUtils.getRoomList(userId.toString(), null, null);
                    Set<String> collect = roomList.stream().collect(Collectors.toSet());
                    for (String room : collect) {
                        client.joinRoom(room);
                    }
                    UUID sessionId = client.getSessionId();
                    System.out.println(sessionId);
                    System.out.println(client.getAllRooms());
                }else {
                    client.disconnect();
                }

//                clients.add(client);

            }
        });
        //添加断开连接的监听器
        this.server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                JwtUtil.JwtResult userInfo = UserAuthorizationListener.getUserInfo(client.getHandshakeData());

                if (userInfo == null){
                    client.disconnect();
                    return;
                }
                Integer userId = userInfo.getUserId();
                List<String> roomList = PushUtils.getRoomList(userId.toString(), null, null);
                for (String room : roomList) {
                    client.leaveRoom(room);
                }


//              clients.remove(client);


            }
        });



    }

    /**
     * 推送消息
     *
     * @param message
     */
    public void push(Message message) {


        Packet packet = new Packet(PacketType.MESSAGE);
        packet.setSubType(PacketType.EVENT);
        packet.setName("message");
        packet.setData(message);
        packet.setNsp(ServerConfigUtils.instance.getWebSocketContext());
//        for (SocketIOClient client : clients) {
//            client.sendEvent("message",packet);
//        }


        Integer userId = message.getUserId();
        String room = PushUtils.getRoom(null, userId, null);


//        SocketIONamespace namespace = server.getNamespace(ServerConfigUtils.instance.getWebSocketContext());

        SocketIONamespace socketIONamespace = server.getAllNamespaces().stream().findFirst().get();

        Iterable<SocketIOClient> roomClients = ((Namespace)socketIONamespace).getRoomClients(room);
        Iterator<SocketIOClient> iterator = roomClients.iterator();

        while (iterator.hasNext()){
            iterator.next().sendEvent("message",packet);

        }



    }

    /**
     * 同步启动服务；
     */
    public void start() {
        try {
            server.start();
        } catch (Exception e) {
            log.error("Push server start failed!", e);
            System.exit(-1);
        }
    }

    /**
     * 停止服务
     */
    public void stop() {
        server.stop();
    }

//    public Map<String, Object> getStatus() {
//        HashMap<String, Object> status = new HashMap<>();
//        status.put("namespace", pushNamespace.getName());   // namespace
//        status.put("rooms", pushNamespace.getRooms());
//        status.put("clients", pushNamespace.getAllClients().size());
//        return status;
//    }

}
